package comparisons

import "jvmgo/ch05/instructions/base"
import "jvmgo/ch05/rtda"

/*
    比较栈顶两个int值
 */

//v1 == v2
type IF_ICMPEQ struct {
    base.BranchInstruction
}

func (self *IF_ICMPEQ) Execute(frame *rtda.Frame) {
    if val1, val2 := _icmpPop(frame); val1 == val2 {
        base.Branch(frame, self.Offset)
    }
}

//v1 != v2
type IF_ICMPNE struct {
    base.BranchInstruction
}

func (self *IF_ICMPNE) Execute(frame *rtda.Frame) {
    if val1, val2 := _icmpPop(frame); val1 != val2 {
        base.Branch(frame, self.Offset)
    }
}

//v1 < v2
type IF_ICMPLT struct {
    base.BranchInstruction
}

func (self *IF_ICMPLT) Execute(frame *rtda.Frame) {
    if val1, val2 := _icmpPop(frame); val1 < val2 {
        base.Branch(frame, self.Offset)
    }
}

//v1 <= v2
type IF_ICMPLE struct {
    base.BranchInstruction
}

func (self *IF_ICMPLE) Execute(frame *rtda.Frame) {
    if val1, val2 := _icmpPop(frame); val1 <= val2 {
        base.Branch(frame, self.Offset)
    }
}

//v1 > v2
type IF_ICMPGT struct {
    base.BranchInstruction
}

func (self *IF_ICMPGT) Execute(frame *rtda.Frame) {
    if val1, val2 := _icmpPop(frame); val1 > val2 {
        base.Branch(frame, self.Offset)
    }
}

//v1 >= v2
type IF_ICMPGE struct {
    base.BranchInstruction
}

func (self *IF_ICMPGE) Execute(frame *rtda.Frame) {
    if val1, val2 := _icmpPop(frame); val1 >= val2 {
        base.Branch(frame, self.Offset)
    }
}

func _icmpPop(frame *rtda.Frame) (val1, val2 int32) {
    stack := frame.OperandStack()
    val2 = stack.PopInt()
    val1 = stack.PopInt()
    return
}
